package io.github.uicdb.et.data.recipe;

import io.github.uicdb.et.ModElements;
import io.github.uicdb.et.element.BasicElement;
import io.github.uicdb.et.item_data.ItemElementData;
import io.github.uicdb.et.recipe.ElementRecipePart;
import io.github.uicdb.et.recipe.TurnInRecipe;
import io.github.uicdb.et.recipe.TurnInRecipeHandler;
import io.github.uicdb.et.recipe.handler.AttachElementHandler;
import io.github.uicdb.et.recipe.handler.ToItemStackHandler;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import net.minecraft.advancements.Criterion;
import net.minecraft.core.Holder;
import net.minecraft.data.recipes.RecipeBuilder;
import net.minecraft.data.recipes.RecipeOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Ingredient;
import net.neoforged.neoforge.common.crafting.ICustomIngredient;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class TurnInRecipeBuilder implements RecipeBuilder {
    final ElementRecipePart element;
    final Ingredient input;
    final TurnInRecipeHandler recipeHandler;
    int recipeTime = 25;
    public TurnInRecipeBuilder recipeTime(int time) {
        this.recipeTime = time;
        return this;
    }

    /**
     * 灌注配方
     * @param element 输入元素
     * @param input 输入物品
     * @param recipeHandler 输出物品处理器
     */
    public static TurnInRecipeBuilder of(ElementRecipePart element, Ingredient input, TurnInRecipeHandler recipeHandler) {
        return new TurnInRecipeBuilder(element, input, recipeHandler);
    }

    public static TurnInRecipeBuilder of(ElementRecipePart element, Ingredient input, ItemElementData data) {
        return of(element, input,new AttachElementHandler(data.getElement(),data.getAmount(),data.getTicks()));
    }
    public static TurnInRecipeBuilder of(Holder<BasicElement> element, int elementInput, TagKey<Item> tag, int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(element, elementInput), Ingredient.of(tag), new ItemElementData(element, elementOutPut, elementTime));
    }

    public static TurnInRecipeBuilder of(ModElements elements, int elementInput, TagKey<Item> tag, int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(elements.holder(), elementInput), Ingredient.of(tag), new ItemElementData(elements.holder(), elementOutPut, elementTime));
    }

    public static TurnInRecipeBuilder of(ModElements elements, int elementAmount, TagKey<Item> tag, int elementTime) {
        return of(new ElementRecipePart(elements.holder(), elementAmount), Ingredient.of(tag), new ItemElementData(elements.holder(), elementAmount, elementTime));
    }

    public static TurnInRecipeBuilder of(ModElements elements, int elementInput, Ingredient input, ModElements outElement,int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(elements.holder(), elementInput), input, new ItemElementData(outElement.holder(), elementOutPut, elementTime));
    }
    public static TurnInRecipeBuilder of(Holder<BasicElement> inputElement, int elementInput, Ingredient input, Holder<BasicElement> outElement,int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(inputElement, elementInput), input, new ItemElementData(outElement, elementOutPut, elementTime));
    }
    public static TurnInRecipeBuilder of(ModElements elements, int elementInput, ICustomIngredient input, int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(elements.holder(), elementInput), new Ingredient(input), new ItemElementData(elements.holder(), elementOutPut, elementTime));
    }

    public static TurnInRecipeBuilder of(Holder<BasicElement> element, int elementAmount, TagKey<Item> tag, int elementTime) {
        return of(new ElementRecipePart(element, elementAmount), Ingredient.of(tag), new ItemElementData(element, elementAmount, elementTime));
    }

    public static TurnInRecipeBuilder of(Holder<BasicElement> element, int elementInput, Ingredient input, int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(element, elementInput), input, new ItemElementData(element, elementOutPut, elementTime));
    }

    public static TurnInRecipeBuilder of(Holder<BasicElement> element, int elementInput, ICustomIngredient input, int elementOutPut, int elementTime) {
        return of(new ElementRecipePart(element, elementInput), new Ingredient(input), new ItemElementData(element, elementOutPut, elementTime));
    }

    /**
     * 合成物品
     * @param element 输入元素
     * @param elementInput 输入元素量
     * @param input 输入物品
     * @param result 结果物品
     */
    public static TurnInRecipeBuilder ofItem(Holder<BasicElement> element, int elementInput, Ingredient input, ItemStack result) {
        return of(new ElementRecipePart(element, elementInput), input, new ToItemStackHandler(result));
    }
    @Override
    public @NotNull Item getResult() {
        return Items.AIR;
    }

    @Override
    public RecipeBuilder unlockedBy(String s, Criterion<?> criterion) {
        return this;
    }

    @Override
    public RecipeBuilder group(@Nullable String s) {
        return this;
    }

    @Override
    public void save(RecipeOutput recipeOutput, ResourceLocation resourceLocation) {
        recipeOutput.accept(resourceLocation, new TurnInRecipe(element, input, recipeHandler,recipeTime), null);
    }
}
